
#pragma once

#include "ttg/services.h"
#include "ttg/pipeline.h"
#include "PerfTestUtils.h"

using namespace System;
using namespace ttg;
using namespace ttg::pipeline;

class CriticalNode: public TimeWasterNode<int> {
protected:
	virtual void postWaste(double t, const int &n) {
		switch (n) {
			case 0:
				getParametrizedOutputs()[1]->sendThis(make_pair(t, 1));
				for (int i = 0; i < 16; i++)
					getParametrizedOutputs()[0]->sendThis(make_pair(10 * t, 2));
				break;
			case 1:
				sendNext(make_pair(200 * t, 3));
				break;
		};
	}
};

namespace ttg_internal
{
	namespace utils
	{

		///<summary>
		///
		///
		///</summary>
		public ref class CriticalPathTest
		{
			typedef pair<double, int> myType;
			private:
				///<summary>
				///
				///
				///</summary>
			public:
				//performs
				static double perform(size_t task_size, size_t thread_count)
				{
					if (task_size > 0 && thread_count > 0)
					{
						//Preparing pipeline
						//Generating conveyor in form of .<:_.
						//       /-*-----\
						//-*----<         >---
						//       \-*---*-/
						Pipeline<myType, myType> *pl
							//Avast!
							= new Pipeline<myType, myType>(/*thread_count,*/ wrap(new CriticalNode()) + ((wrap(new CriticalNode()) + wrap(new CriticalNode())) * wrap(new CriticalNode())));
						//Launching
						double t_start = ttg::services::ServiceBase::_Timer().getMilliSeconds();
						pl->start(make_pair(1.0 * task_size, 0));
						double t_end = ttg::services::ServiceBase::_Timer().getMilliSeconds();
						//Returning elapsed time
						SAFE_DELETE(pl);
						return t_end - t_start;
					}
					else
						return 0.0;
				}
		};
	}
}
